www.gusucode.com > VC++网络版的打字软件源程序-源码程序 > VC++网络版的打字软件源程序-源码程序\code\TypeClt V2.0\TypeOperatorView.cpp

    //Download by http://www.NewXing.com
// TypeOperatorView.cpp : implementation file
//

#include "stdafx.h"
#include "type.h"
#include "TypeDoc.h"
#include "TypeOperatorView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTypeOperatorView

IMPLEMENT_DYNCREATE(CTypeOperatorView, CView)

CTypeOperatorView::CTypeOperatorView()
{
	Init();
}

CTypeOperatorView::~CTypeOperatorView()
{
	if(m_pIL)
	{
		delete m_pIL;
		m_pIL=NULL;
	}
	if(m_bIsTest==TRUE && m_bIsPause==FALSE)
	{
		KillTimer(TIMER_SHOW_SCORE_ID);
	}

	m_TypeWordList.RemoveAll();
}


BEGIN_MESSAGE_MAP(CTypeOperatorView, CView)
	//{{AFX_MSG_MAP(CTypeOperatorView)
	ON_WM_CHAR()
	ON_WM_TIMER()
	ON_COMMAND(ID_PAUSE_TEST, OnPauseTest)
	ON_UPDATE_COMMAND_UI(ID_PAUSE_TEST, OnUpdatePauseTest)
	ON_COMMAND(ID_CONTINUE_TEST, OnContinueTest)
	ON_UPDATE_COMMAND_UI(ID_CONTINUE_TEST, OnUpdateContinueTest)
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTypeOperatorView drawing

void CTypeOperatorView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
	CRect rc;
	GetClientRect(rc);

	/*双缓存
	CRect rect=rc;
	CDC		memDC;
	CBitmap memBMP;
	memDC.CreateCompatibleDC(pDC);
	memBMP.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
	CBitmap*pOldBMP=memDC.SelectObject(&memBMP);
	SetRect(rc);
	DrawPage(&memDC,m_nCurPage);
	pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
	*/
	
	SetRect(rc);
	DrawPage(pDC,m_nCurPage);
}

/////////////////////////////////////////////////////////////////////////////
// CTypeOperatorView diagnostics

#ifdef _DEBUG
void CTypeOperatorView::AssertValid() const
{
	CView::AssertValid();
}

void CTypeOperatorView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTypeOperatorView message handlers
/////////////////////////////////////////////////////////
//选择输入法
void CTypeOperatorView::SelectInputLanguage(int nIL)
{
	if(!m_pIL)
	{
		return ;
	}

	CString strName;

	switch(nIL)
	{
	case EN_INPUT_LANGUAGE://英文输入法
		strName="美式键盘";
		break;
	case PY_INPUT_LANGUAGE://拼音输入法默认为智能ABC
		strName="智能 ABC";
		break;
	case WB_INPUT_LANGUAGE:
		strName="五笔";
		break;
	default:
		strName="美式键盘";
		break;
	}

	IL* pIL=m_pIL->GetInputLanguageList();
	CString str;
	while(pIL)
	{
		str=pIL->szName;
		if(str.Find(strName,0)!=-1)
		{
			m_pIL->SelectInputLanguage(pIL);
			return ;
		}
		pIL=pIL->pNext;
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CTypeOperatorView::LoadQuestion(CString strText, CString strTitle, long lTestTime, int nInputLanguage)
{
	m_Question.strText=strText;
	m_Question.strTitle=strTitle;
	m_Question.lTestTime=lTestTime;
	m_Question.nInputLanguage=nInputLanguage;
	
	if(m_pIL!=NULL)
	{
		delete m_pIL;
		m_pIL=NULL;
	}
	m_pIL=new CInputLanguage;
	
	SelectInputLanguage(nInputLanguage);//选择输入法

	FormatQuestion();	//格式化试题
}

///////////////////////////////////////////////
//设置打字区域
void CTypeOperatorView::SetRect(CRect &rcType)
{
	int nRows	= m_nPageRows;
	int nCols	= m_nPageCols;
	
	m_rcType.SetRect(rcType.left,rcType.top,rcType.right,rcType.bottom);
	
	if(m_bShowHead)
	{	
		nRows++;
	}
	if(m_bShowFoot)
	{
		nRows++;
	}

	int nRowHeight	= rcType.Height()/nRows;
	int nColWidth	= rcType.Width()/m_nPageCols;

	/*微调*/
	rcType.left		+= (rcType.Width() % m_nPageCols)/2;
	rcType.right	=rcType.left+nCols*nColWidth;
	rcType.top		+= (rcType.Height() % nRows)/2;
	rcType.bottom	=rcType.top+nRows*nRowHeight;

	/*行高和列宽设置*/
	m_nRowHeight	= nRowHeight-m_nRowOffset;
	m_nColWidth		= nColWidth;

	/*区域设置*/
	m_rcPage.SetRect(rcType.left,rcType.top,rcType.right,rcType.bottom);

	if(m_bShowHead)
	{
		m_rcHead.SetRect(rcType.left, rcType.top, rcType.right, rcType.top+nRowHeight);
		m_rcPage.DeflateRect(0,nRowHeight,0,0);
	}
	if(m_bShowFoot)
	{
		m_rcFoot.SetRect(rcType.left, rcType.bottom-nRowHeight, rcType.right, rcType.bottom);
		m_rcPage.DeflateRect(0,0,0,nRowHeight);
	}
}

/////////////////////////////////////////////
//创建新字体
void CTypeOperatorView::CreateFont()
{
	LOGFONT lf;
	memset(&lf,0,sizeof(LOGFONT));
	
	lf.lfHeight=MulDiv(7,-m_nRowHeight,10);
	//lf.lfWidth=m_nColWidth/3;

	strcpy(lf.lfFaceName,"黑体");

	if(m_pWordFont!=NULL)
	{
		delete m_pWordFont;
		m_pWordFont=NULL;
	}

	m_pWordFont=new CFont;
	m_pWordFont->CreateFontIndirect(&lf);
}

void CTypeOperatorView::BeginTest()
{
	m_bIsTest=TRUE;
	m_bIsPause=FALSE;
	m_lStartTime=GetTickCount();
	
	SetTimer(TIMER_SHOW_SCORE_ID,500,NULL);
}

void CTypeOperatorView::PauseTest()
{
	m_bIsPause=TRUE;
	m_lCurPauseTime=GetTickCount();
	KillTimer(TIMER_SHOW_SCORE_ID);
}

void CTypeOperatorView::ContinueTest()
{
	m_bIsPause=FALSE;
	m_lTotalStopTime+=(GetTickCount()-m_lCurPauseTime);
	SetTimer(TIMER_SHOW_SCORE_ID,500,NULL);
}

void CTypeOperatorView::StopTest()
{
	m_bIsTest=FALSE;
	m_bIsPause=FALSE;
	KillTimer(TIMER_SHOW_SCORE_ID);
}

void CTypeOperatorView::EndTest()
{
	StopTest();	
	SaveScore(m_nRate,m_nSpeed);

	CTypeDoc* pDoc=(CTypeDoc*)GetDocument();
	pDoc->ShowMainView();
}

/////////////////////////////////////////////////
//初始化
void CTypeOperatorView::Init()
{
	m_bIsTest=FALSE;					//还没测试
	
	m_pIL=NULL;

	m_rcType.SetRect(0,0,0,0);			//打字测试区域

	m_strFilter					= "";	//过滤字符系列
	m_Question.strText			= "";
	m_Question.strTitle			= "";
	m_Question.lTestTime		= DEFAULT_TEST_TIME;
	m_Question.nInputLanguage	= DEFAULT_INPUT_LANGUAGE;
	m_TypeWordList.RemoveAll();

	m_nWords		= 0;		//总字数
	m_nCurWord		= 0;		//当前字

	/*页面信息*/
	m_nPages		= 0;		//总页数
	m_nCurPage		= 0;		//当前页
	m_nPageRows		= MAX_ROWS;	//每页的总行数
	m_nPageCols		= MAX_COLS;	//每页的总列数
	m_nCurRow		= 0;		//当前行
	m_nCurCol		= 0;		//当前列
	m_rcPage.SetRect(0,0,0,0);	//页的显示区域
	m_nRowHeight	= 0;		//行高
	m_nColWidth		= 0;		//列宽
	m_nRowOffset	= 10;		//行间距

	m_bShowGrides	= TRUE;		//是否显示格子
	/*文字格式*/
	m_pWordFont				= NULL;						//文字的字体
	m_clfNormalText			= RGB(0,0,0);				//还没录入时文字的颜色
	m_clfNormalBackground	= GetSysColor(COLOR_3DFACE);//还没录入时文字的背景色
	m_clfRightText			= RGB(0,0,255);				//正确录入时文字的颜色
	m_clfRightBackground	= RGB(0,255,0);				//正确录入时文字的背景色
	m_clfWrongText			= RGB(255,0,0);			//错误录入时文字的颜色
	m_clfWrongBackground	= RGB(255,215,215);				//错误录入时文字的背景色
	m_clfFill				= GetSysColor(COLOR_3DLIGHT);//填充颜色
	m_clfLine				= GetSysColor(COLOR_3DSHADOW);//线条颜色

	/*页眉页脚信息*/
	m_bShowHead		= TRUE;		//是否显示页眉
	m_rcHead.SetRect(0,0,0,0);		//显示页眉区域
	m_bShowFoot		= TRUE;		//是否显示页脚
	m_rcFoot.SetRect(0,0,0,0);		//显示页脚区域

	/*当前成绩*/
	m_nRightWords	= 0;		//正确字数
	m_nWrongWords	= 0;		//错误字数
	m_nLeaveWords	= 0;		//剩余字数
	m_nSpeed		= 0;		//速度
	m_nRate			= 0;		//正确率

	/*测试时间*/
	m_bIsPause			=FALSE;				//是否暂停测试
	m_lCurPauseTime		=GetTickCount();	//暂停时的时间
	m_lStartTime		= GetTickCount();	//开始测试时间
	m_lTotalStopTime	= 0;				//总暂停时间

}

////////////////////////////////////////////////////////////////////////////////////////////////////
//判断是否时间到了
BOOL CTypeOperatorView::IsStopTime()
{
	long lt=(GetTickCount()-m_lStartTime-m_lTotalStopTime)/1000;
	return (lt>=m_Question.lTestTime);
}

///////////////////////////////////////////////////
//判断一个字符是否是中文字符
BOOL CTypeOperatorView::IsChineseChar(char c)
{
	UINT uChar=(UINT)c;
	return (uChar>=0xa1);
}

///////////////////////////////////////////////////
//在试题字符列表中增加一个字符
void CTypeOperatorView::AddWord(CString strText, int nFlag, int nState)
{
	TYPEWORDDEF tw;
	tw.strText=strText;
	tw.nFlag=nFlag;
	tw.nState=nState;
	m_TypeWordList.Add(tw);
}
/////////////////////////////////////////////////
//输入一个字符
void CTypeOperatorView::InputChar(char cChar)
{
	CDC* pDC=GetDC();
	static char	cOldChar;//前一个字符
	static BOOL	bIsFirstCNChar=FALSE;
	CString		strText;
	TYPEWORDDEF tw;

	/*没有试题或还没开始测试时返回*/
	if(m_nWords==0 || !m_bIsTest || m_bIsPause)
	{
		return;
	}

	if(cChar==VK_BACK)
	{	
		if(IsLastWord())
		{
			if(m_TypeWordList.GetAt(m_nWords-1).nState==STATE_NORMAL)
			{
				MovePrev();
			}
		}
		else
		{
			MovePrev();
		}

		tw=m_TypeWordList.GetAt(m_nCurWord);
		tw.nState=STATE_NORMAL;
		m_TypeWordList.SetAt(m_nCurWord,tw);
		DrawWord(pDC,m_nCurPage,m_nCurRow,m_nCurCol);
		ShowCaretEx(m_nCurRow,m_nCurCol);
		if(pDC)
		{
			ReleaseDC(pDC);
			pDC=NULL;
		}
		return;
	}

	tw=m_TypeWordList.GetAt(m_nCurWord);
	if(IsChineseChar(cChar)==FALSE)
	{//英文字母处理模块
		strText.Format("%c",cChar);
		
		cOldChar=cChar;

		if(strText==tw.strText)
		{
			tw.nState=STATE_RIGHT;
			Beep(800*1,100);
		}
		else
		{
			tw.nState=STATE_WRONG;
			Beep(800*2,100);
		}
		
		m_TypeWordList.SetAt(m_nCurWord,tw);
		DrawWord(pDC,m_nCurPage,m_nCurRow,m_nCurCol);
		if(IsLastWord())
		{
			EndTest();
		}
		else
		{
			MoveNext();
			ShowCaretEx(m_nCurRow,m_nCurCol);//显示光标
		}
		if(pDC)
		{
			ReleaseDC(pDC);
			pDC=NULL;
		}
		return;
	}
	
	//////////////////////////////////////////
	//汉字处理模块
	//////////////////////////////////////////
	bIsFirstCNChar=!bIsFirstCNChar;

	if(bIsFirstCNChar)
	{//当前的字符是第一个汉字字符
		cOldChar=cChar;
		if(pDC)
		{
			ReleaseDC(pDC);
			pDC=NULL;
		}
		return;
	}
		
	//当前的字符是第二个汉字字符
	strText.Format("%c%c",cOldChar,cChar);
	cOldChar=cChar;

	if(strText==tw.strText)
	{
		tw.nState=STATE_RIGHT;
		Beep(800*1,100);
	}
	else
	{
		tw.nState=STATE_WRONG;
		Beep(800*2,100);
	}

	m_TypeWordList.SetAt(m_nCurWord,tw);

	DrawWord(pDC,m_nCurPage,m_nCurRow,m_nCurCol);

	if(IsLastWord())
	{
		EndTest();
	}
	else
	{
		MoveNext();
		ShowCaretEx(m_nCurRow,m_nCurCol);//显示光标
	}

	if(pDC)
	{
		ReleaseDC(pDC);
		pDC=NULL;
	}
}

///////////////////////////////////////////////////
//格式化试题
void CTypeOperatorView::FormatQuestion()
{
	CString		strText;
	char		cOldChar;//前一个字符
	char		cChar;
	BOOL		bIsFirstCNChar=FALSE;
	int			nLen=m_Question.strText.GetLength();

	if(m_bIsTest)//如果正在测试,则关闭
	{
		StopTest();
	}

	m_TypeWordList.RemoveAll();

	m_nWords		= 0;		//总字数
	m_nCurWord		= 0;		//当前字

	m_nPages		= 0;		//总页数
	m_nCurPage		= 0;		//当前页
	m_nCurRow		= 0;		//当前行
	m_nCurCol		= 0;		//当前列

	/*当前成绩*/
	m_nRightWords	= 0;		//正确字数
	m_nWrongWords	= 0;		//错误字数
	m_nLeaveWords	= 0;		//剩余字数
	m_nSpeed		= 0;		//速度
	m_nRate			= 0;		//正确率

	m_lCurPauseTime		=GetTickCount();	//暂停时的时间
	m_lStartTime		= GetTickCount();	//开始测试时间
	m_lTotalStopTime	= 0;				//总暂停时间

	for(int i=0;i<nLen;i++)
	{
		cChar=(char)m_Question.strText.GetAt(i);
	
		/*过滤字符*/
		if(m_strFilter.Find(cChar,0)!=-1)
		{
			continue;
		}

		if(IsChineseChar(cChar)==FALSE)
		{//非中文字字符处理模块
			strText.Format("%c",cChar);
			if((cChar>='a' && cChar<='z') || (cChar>='A' && cChar<='Z'))
			{//英文字母
				AddWord(strText,FLAG_EN,STATE_NORMAL);
			}
			else
			{//其它非中文字符
				AddWord(strText,FLAG_TH,STATE_NORMAL);
			}
			m_nWords++;
			cOldChar=cChar;
			continue;
		}
	
		//////////////////////////////////////////
		//汉字处理模块
		//////////////////////////////////////////
		bIsFirstCNChar=!bIsFirstCNChar;

		if(bIsFirstCNChar)
		{//当前的字符是第一个汉字字符
			cOldChar=cChar;
			continue;
		}
		
		//当前的字符是第二个汉字字符
		strText.Format("%c%c",cOldChar,cChar);
		AddWord(strText,FLAG_CN,STATE_NORMAL);//中文字符
		m_nWords++;
		cOldChar=cChar;
	}

	/*计算总页数*/
	int nPageWords = m_nPageRows*m_nPageCols;
	if(m_nWords % nPageWords == 0)
	{
		m_nPages = m_nWords/nPageWords;
	}
	else
	{
		m_nPages = m_nWords/nPageWords+1;
	}
}

///////////////////////////////////////////////////
//移到下一个位置
void CTypeOperatorView::MoveNext()
{
	if(m_nCurWord==m_nWords-1)
		return;//当前位置是最后一

	m_nCurWord++;

	if(m_nCurCol<m_nPageCols-1)
	{
		m_nCurCol++;
	}
	else
	{
		m_nCurCol=0;
		
		if(m_nCurRow<m_nPageRows-1)
		{
			m_nCurRow++;
		}
		else
		{
			m_nCurRow=0;
			m_nCurPage++;
			Invalidate();
		}
	}
}

///////////////////////////////////////////////////
//移到上一个位置
void CTypeOperatorView::MovePrev()
{
	if(m_nCurWord==0)
		return;//当前位置是第一个

	m_nCurWord--;

	if(m_nCurCol>0)
	{
		m_nCurCol--;
	}
	else
	{
		m_nCurCol=m_nPageCols-1;

		if(m_nCurRow>0)
		{
			m_nCurRow--;
		}
		else
		{
			m_nCurRow=m_nPageRows-1;
			m_nCurPage--;
			Invalidate();
		}
	}

}

/////////////////////////////////////////////////////////////
//获取某行的区域
void CTypeOperatorView::GetRowRect(CRect &rc, int nRow)
{
	rc.left		= m_rcPage.left;
	rc.right	= m_rcPage.right;
	rc.top		= m_rcPage.top+nRow*(m_nRowHeight+m_nRowOffset);
	rc.bottom	= rc.top+m_nRowHeight;
}

///////////////////////////////////////////////////////////////////
//获取某行某列字的区域
void CTypeOperatorView::GetWordRect(CRect &rc, int nRow, int nCol)
{
	GetRowRect(rc,nRow);
	rc.left+=nCol*m_nColWidth;
	rc.right=rc.left+m_nColWidth;
}

//////////////////////////////////////////////////////////////////
//获取某行某列光标的区域
void CTypeOperatorView::GetCaretRect(CRect &rc, int nRow, int nCol)
{
	GetWordRect(rc,nRow,nCol);
	rc.top=rc.bottom+1;
	rc.bottom=rc.top+m_nRowOffset/4;
}

////////////////////////////////////////////////////////////
//画3D矩形
void CTypeOperatorView::Draw3dRect(CDC *pDC, CRect &rc, COLORREF clfFill)
{
	pDC->FillSolidRect(rc,clfFill);
	rc.DeflateRect(1,1);
	pDC->Draw3dRect(rc,GetSysColor(COLOR_3DLIGHT),GetSysColor(COLOR_3DSHADOW));
}

//////////////////////////////////////////////////////
//画页眉
void CTypeOperatorView::DrawHead(CDC *pDC, int nPage)
{
	CRect rc=m_rcHead;
	CString str;
	Count(str);
	pDC->FillSolidRect(rc,m_clfFill);
	rc.DeflateRect(1,1,1,m_nRowOffset);

	CFont* pOldFont=pDC->SelectObject(m_pWordFont);
	pDC->DrawText(str,rc,DT_LEFT | DT_SINGLELINE | DT_VCENTER);
	pDC->SelectObject(pOldFont);
}

//////////////////////////////////////////////////////
//画页脚
void CTypeOperatorView::DrawFoot(CDC *pDC, int nPage)
{
	CString strText;
	int		nOffset=10;
	int		nTextWidth;
	int		nBkMode;

	pDC->FillSolidRect(m_rcFoot,m_clfFill);
	
	CRect rcFoot=m_rcFoot;
	rcFoot.DeflateRect(0,m_nRowOffset/2,0,m_nRowOffset/2);

	CFont* pOldFont=pDC->SelectObject(m_pWordFont);

	/*图例*/
	strText="文字状态图例: ";
	CRect rcState=rcFoot;
	nTextWidth=pDC->GetTextExtent(strText).cx;
	rcState.right=rcState.left+nTextWidth;
	nBkMode=pDC->SetBkMode(TRANSPARENT);
	pDC->DrawText(strText,rcState,DT_LEFT | DT_VCENTER | DT_SINGLELINE);
	pDC->SetBkMode(nBkMode);

	strText="  未录入  ";
	rcState.OffsetRect(nTextWidth+nOffset,0);
	CRect rcNormal=rcState;
	nTextWidth=pDC->GetTextExtent(strText).cx;
	rcNormal.right=rcNormal.left+nTextWidth;
	DrawWord(pDC,rcNormal,strText,STATE_NORMAL);

	strText="  正 确  ";
	rcState.OffsetRect(nTextWidth+nOffset,0);
	CRect rcRight=rcState;
	nTextWidth=pDC->GetTextExtent(strText).cx;
	rcRight.right=rcRight.left+nTextWidth;
	DrawWord(pDC,rcRight,strText,STATE_RIGHT);
	
	strText="  错 误  ";
	rcState.OffsetRect(nTextWidth+nOffset,0);
	CRect rcWrong=rcState;
	nTextWidth=pDC->GetTextExtent(strText).cx;
	rcWrong.right=rcWrong.left+nTextWidth;
	DrawWord(pDC,rcWrong,strText,STATE_WRONG);

	strText.Format("第%d页 / 共%d页    %d X %d = %d",
		m_nCurPage+1,m_nPages,m_nPageCols,m_nPageRows,
		m_nPageCols*m_nPageRows);
	CRect rcPageInfo=rcFoot;
	rcPageInfo.left=rcState.right;
	nBkMode=pDC->SetBkMode(TRANSPARENT);
	pDC->DrawText(strText,rcPageInfo,DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
	pDC->SetBkMode(nBkMode);

	pDC->SelectObject(pOldFont);
}
////////////////////////////////////////////////////////////////////
//画某一页
void CTypeOperatorView::DrawPage(CDC *pDC, int nPage)
{
	int nRow;
	int nCol;

	CreateFont();//创建字体

	pDC->FillSolidRect(m_rcType,m_clfFill);

	/*画页眉*/
	if(m_bShowHead)
	{
		DrawHead(pDC,nPage);
	}

	/*画格子*/
	pDC->FillSolidRect(m_rcPage,m_clfFill);
	CPen* pNewPen=new CPen;
	pNewPen->CreatePen(PS_SOLID,1,m_clfLine);
	CPen* pOldPen=pDC->SelectObject(pNewPen);

	CRect rcRow;
	for(nRow=0; nRow<m_nPageRows; nRow++)
	{
		GetRowRect(rcRow,nRow);
		pDC->Rectangle(rcRow);

		if(m_bShowGrides)
		{
			for(nCol=1; nCol<m_nPageCols; nCol++)
			{
				pDC->MoveTo(rcRow.left+nCol*m_nColWidth, rcRow.top+1);
				pDC->LineTo(rcRow.left+nCol*m_nColWidth, rcRow.bottom-1);
			}
		}
	}
	pDC->SelectObject(pOldPen);
	delete pNewPen;
	pNewPen=NULL;

	/*画字*/
	for(nRow=0; nRow<m_nPageRows; nRow++)
	{
		for(nCol=0; nCol<m_nPageCols; nCol++)
		{
			DrawWord(pDC,nPage,nRow,nCol);
		}
	}

	/*正在测试时显示光标*/
	if(m_bIsTest==TRUE || m_nCurWord==0)
	{
		ShowCaretEx(m_nCurRow,m_nCurCol);
	}
	else
	{
		HideCaret();
	}

	/*画页脚*/
	if(m_bShowFoot)
	{
		DrawFoot(pDC,nPage);
	}
}

/////////////////////////////////////////////////////////////////////////
//画某一页某一行某一列的字
void CTypeOperatorView::DrawWord(CDC *pDC, CRect &rc, CString str, int nState)
{
	COLORREF	clfText;
	COLORREF	clfBackground;

	switch(nState)
	{
	case STATE_NORMAL:
		clfText			=m_clfNormalText;
		clfBackground	=m_clfNormalBackground;
		break;
	case STATE_RIGHT:
		clfText			=m_clfRightText;
		clfBackground	=m_clfRightBackground;
		break;
	case STATE_WRONG:
		clfText			=m_clfWrongText;
		clfBackground	=m_clfWrongBackground;
		break;
	}
	
	//填充
	if(m_bShowGrides)
	{
		Draw3dRect(pDC,rc,clfBackground);
	}

	//画字
	CFont* pOldFont=pDC->SelectObject(m_pWordFont);

	COLORREF	oClf=pDC->SetTextColor(clfText);
	int			nMode=pDC->SetBkMode(TRANSPARENT);
	pDC->DrawText(str,rc,DT_CENTER | DT_SINGLELINE | DT_VCENTER);
	pDC->SetBkMode(nMode);
	pDC->SetTextColor(oClf);
	
	pDC->SelectObject(pOldFont);
}
/////////////////////////////////////////////////////////////////////////////////
void CTypeOperatorView::DrawWord(CDC *pDC, int nPage, int nRow, int nCol)
{
	int nPageWords	= m_nPageRows*m_nPageCols;
	int nWords		= nPage*nPageWords+nRow*m_nPageCols+nCol;
	
	if(nWords>=m_nWords || nWords<0)
	{
		return;
	}

	TYPEWORDDEF tw		=m_TypeWordList.GetAt(nWords);
	CString		strText	=tw.strText;
	int			nState	=tw.nState;

	CRect		rcWord;
	GetWordRect(rcWord,nRow,nCol);
	DrawWord(pDC,rcWord,strText,nState);
}


void CTypeOperatorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	CView::OnChar(nChar, nRepCnt, nFlags);	
	// TODO: Add your message handler code here and/or call default
	if(m_nWords!=0 && m_nCurWord==0 && m_bIsTest==FALSE)
	{
		BeginTest();
	}

	if(m_nWords!=0 && m_bIsTest==TRUE && m_bIsPause==TRUE)
	{
		ContinueTest();
	}
	
	char c=(char)nChar;

	InputChar(c);
}

////////////////////////////////////////////////////////////
//显示光标
void CTypeOperatorView::ShowCaretEx(int nRow, int nCol)
{
	CRect rcCaret;
	GetCaretRect(rcCaret,nRow,nCol);
	HideCaret();
	::CreateCaret(m_hWnd,NULL,rcCaret.Width(),rcCaret.Height());
	CPoint pt(rcCaret.left,rcCaret.top);
	SetCaretPos(pt);
	ShowCaret();
}

//////////////////////////////////////////////////
//统计函数
//速度=正确数*60*1000/time;(单位:个/分)
//正确率=正确数*100/(正确数+错误数)(单位:%)
void CTypeOperatorView::Count(CString &str)
{
	long lTotalTime=(GetTickCount()-m_lStartTime)-m_lTotalStopTime;
	long lLeaveTime=m_Question.lTestTime-lTotalTime/1000;
	
	int nRightWords=0;
	int nWrongWords=0;
	int nNormalWords=0;
	for(int i=0;i<m_nWords;i++)
	{
		switch(m_TypeWordList.GetAt(i).nState)
		{
		case STATE_NORMAL:
			nNormalWords++;
			break;
		case STATE_RIGHT:
			nRightWords++;
			break;
		case STATE_WRONG:
			nWrongWords++;
			break;
		}
		
	}
	m_nRightWords=nRightWords;
	m_nWrongWords=nWrongWords;
	m_nLeaveWords=nNormalWords;

	if(lTotalTime==0 || (nRightWords+nWrongWords)==0)
	{
		m_nSpeed=0;
		m_nRate=0;
	}
	else
	{
		m_nSpeed=nRightWords*60*1000/lTotalTime;
		m_nRate=nRightWords*100/(nRightWords+nWrongWords);
	}

	int nMinute=lLeaveTime / 60;
	int nSecond=lLeaveTime % 60;

	if(lLeaveTime<=0)
	{
		nMinute=0;
		nSecond=0;
	}

	str.Format("速度:%3d(个/分) 正确率:%2d(%%)剩余时间:%2d分%2d秒",m_nSpeed,m_nRate,nMinute,nSecond);
}

///////////////////////////////////////////////////////////////////
//时间函数
void CTypeOperatorView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	
	if(IsStopTime())
	{
		StopTest();
	}

	CDC* pDC=GetDC();
	switch(nIDEvent)
	{
	case TIMER_SHOW_SCORE_ID:
		DrawHead(pDC,m_nCurPage);
		break;
	}
	ReleaseDC(pDC);

	CView::OnTimer(nIDEvent);
}

//////////////////////////////////////////////////////////
//保存成绩
void CTypeOperatorView::SaveScore(int nRate, int nSpeed)
{
	CTypeDoc* pDoc=(CTypeDoc*)GetDocument();
	pDoc->SaveScore(nRate,nSpeed);
}

///////////////////////////////////////////////////////////
//获得当前字符
void CTypeOperatorView::GetCurChar(char &c)
{
	if(m_nWords==0)
		return;

	CString strText=m_TypeWordList.GetAt(m_nCurWord).strText;
	c=(char)strText.GetAt(0);
}


void CTypeOperatorView::OnPauseTest() 
{
	// TODO: Add your command handler code here
	PauseTest();
}

void CTypeOperatorView::OnUpdatePauseTest(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(!m_bIsPause);
}

void CTypeOperatorView::OnContinueTest() 
{
	// TODO: Add your command handler code here
	ContinueTest();
}

void CTypeOperatorView::OnUpdateContinueTest(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bIsPause);
}

int CTypeOperatorView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	//CTypeDoc* pDoc=(CTypeDoc*)GetDocument();
	//pDoc->m_pView=this;
	return 0;
}


void CTypeOperatorView::OnInitialUpdate() 
{
	CView::OnInitialUpdate();
	
	// TODO: Add your specialized code here and/or call the base class
	Init();
}

//////////////////////////////////////////////////////////////////////////
//统计英文字字母及每个英文字母的录入情况
//pR,pW,pN均为一个大小为26的整型数组
void CTypeOperatorView::CountEnglishChar(int *pR, int *pW)
{

	int nIndex=0;
	
	for(nIndex=0;nIndex<NUMBER_EN;nIndex++)
	{//初始化累加器
		pR[nIndex]=0;
		pW[nIndex]=0;
	}

	CString strText;
	char cChar;

	for(int i=0;i<m_nWords;i++)
	{
		if(m_TypeWordList.GetAt(i).nFlag==FLAG_EN)
		{
			strText=m_TypeWordList.GetAt(i).strText;
			cChar=strText.GetAt(0);
			if(cChar>='a' && cChar<='z')
			{
				nIndex=cChar-'a';
			}
			else
			{
				nIndex=cChar-'A';
			}

			switch(m_TypeWordList.GetAt(i).nState)
			{
			case STATE_NORMAL:
				break;
			case STATE_RIGHT:
				pR[nIndex]++;
				break;
			case STATE_WRONG:
				pW[nIndex]++;
				break;
			}
		}
	}

}